package com.yixun.driver.config;


import org.apache.http.client.config.RequestConfig;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClientBuilder;
import org.apache.http.impl.conn.PoolingHttpClientConnectionManager;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration
public class HttpClient {
    //最大连接数
    @Value("${http.maxTotal}")
    private Integer maxTotal;

    //并发数
    @Value("${http.defaultMaxPerRoute}")
    private Integer defaultMaxPerRoute;

    //连接超时时间
    @Value("${http.connectTimeout}")
    private Integer connectTimeout;

    //设置从connect Manager获取Connection 超时时间，单位毫秒。这个属性是新加的属性，因为目前版本是可以共享连接池的
    @Value("${http.connectionRequestTimeout}")
    private Integer connectionRequestTimeout;

    //请求获取数据的超时时间，单位毫秒。 如果访问一个接口，多少时间内无法返回数据，就直接放弃此次调用。
    @Value("${http.socketTimeout}")
    private Integer socketTimeout;

    @Value("${http.staleConnectionCheckEnabled}")
    private boolean staleConnectionCheckEnabled;


    //http客户端连接个数管理 socket的客户端的封装 对个数进行管理
    //首先实例化一个连接池管理器，设置最大连接数、并发连接数
    @Bean(name = "httpClientConnectionManager")
    public PoolingHttpClientConnectionManager getHttpClientConnectionManager(){
        PoolingHttpClientConnectionManager httpClientConnectionManager = new PoolingHttpClientConnectionManager();
        //最大连接数
        httpClientConnectionManager.setMaxTotal(maxTotal);
        //并发数
        httpClientConnectionManager.setDefaultMaxPerRoute(defaultMaxPerRoute);
        return httpClientConnectionManager;
    }


    //实例化连接池，设置连接池管理器。
    //这里需要以参数形式注入上面实例化的连接池管理器
    @Bean(name = "httpClientBuilder")
    public HttpClientBuilder getHttpClientBuilder(@Qualifier("httpClientConnectionManager") PoolingHttpClientConnectionManager httpClientConnectionManager){

        //HttpClientBuilder中的构造方法被protected修饰，
        // 所以这里不能直接使用new来实例化一个HttpClientBuilder，
        // 可以使用HttpClientBuilder提供的静态方法create()来获取HttpClientBuilder对象
        HttpClientBuilder httpClientBuilder = HttpClientBuilder.create();

        //把对象当参数设置进去保存起来
        httpClientBuilder.setConnectionManager(httpClientConnectionManager);

        return httpClientBuilder;
    }


    //注入连接池，用于获取httpClient
    @Bean
    public CloseableHttpClient getCloseableHttpClient(@Qualifier("httpClientBuilder") HttpClientBuilder httpClientBuilder){
        //注入连接池，用于获取httpClient
        return httpClientBuilder.build();
    }


     //Builder是RequestConfig的一个内部类
     //通过RequestConfig的custom方法来获取到一个Builder对象
     //设置builder的连接信息
     //这里还可以设置proxy，cookieSpec等属性。有需要的话可以在此设置
    @Bean(name = "builder")
    public RequestConfig.Builder getBuilder(){
        RequestConfig.Builder builder = RequestConfig.custom();
        return builder.setConnectTimeout(connectTimeout)
                .setConnectionRequestTimeout(connectionRequestTimeout)
                .setSocketTimeout(socketTimeout)
                .setStaleConnectionCheckEnabled(staleConnectionCheckEnabled);//连接超时状态状态
    }


    //这个超时可以设置为客户端级别，作为所有请求的默认值：
    //使用builder构建一个RequestConfig对象
    @Bean
    public RequestConfig getRequestConfig(@Qualifier("builder") RequestConfig.Builder builder){
        return builder.build();
    }


//Request不会继承客户端级别的请求配置，
// 所以在自定义Request的时候，
// 需要将客户端的默认配置拷贝过去：
//HttpGet httpget = new HttpGet("http://www.apache.org/");
//    RequestConfig requestConfig = RequestConfig.copy(defaultRequestConfig)
//            .setProxy(new HttpHost("myotherproxy", 8080))
//            .build();
//httpget.setConfig(requestConfig);


//  4.3版本的超时是这样的： 4.5有较大更新
//    public static String httpPost(String url, String jsonString) {
//        // 设置HTTP请求参数
//        String result = null;
//        HttpClient httpClient = new DefaultHttpClient();
//        HttpPost httpPost = new HttpPost(url);
//        try {
//            httpClient.getParams().setParameter(CoreConnectionPNames.CONNECTION_TIMEOUT, 10000);//设置请求超时时间 10s
//            StringEntity entity = new StringEntity(jsonString);
//            entity.setContentEncoding("UTF-8");
//            entity.setContentType("application/json");
//            httpPost.setEntity(entity);
//            HttpEntity resEntity = httpClient.execute(httpPost).getEntity();
//            result = EntityUtils.toString(resEntity, "UTF-8");
//        } catch (Exception e) {
//            logger.error("http接口调用异常：url is::" + url, e);
//            return null;
//        } finally {
//            httpClient.getConnectionManager().shutdown();
//        }
//        return result;
//    }
}
